﻿--[[
------------------------------
Наша Ventril-ко:
Клиент качать с ventrilo.com
ru2.ruvoice.com 
Порт 3791
Пароль: attero
-------------------------------
video 
http://www.youtube.com/user/Barenei
-------------------------------
WWS
http://www.worldoflogs.com/guilds/3424/
spent*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*spent
dkp*159*121*141*87*99*195*0*162*67*21*106*106*80*34*33*185*0*180*dkp
]]

--local NDKP_ENABLE_CHATHOOK=true
--NDKP_ENABLE_CHATHOOK=false

--fix 5.4.1 taints - just Hide that crappy windows
UIParent:HookScript("OnEvent", function(s, e, a1, a2) if e:find("ACTION_FORBIDDEN") and ((a1 or "")..(a2 or "")):find("IsDisabledByParentalControls") then StaticPopup_Hide(e) end; end)
-------------------------------------------

local DEBUG = 10

--local OriginalChatFrame_OnEvent;
--local OriginalUnitPopup_OnClick;

NDKP_LOADED = false
NDKP_LEGAL_LEVEL = 0

NDKP_DISABLE_SORT = false
NDKP_DISABLE_FILTER = false
local isAdmin = true

local NDKP_POSITIVE_COLOR = "|c003FFF3F"
local NDKP_NEGATIVE_COLOR = "|c00FF3F3F"
local NDKP_ZERO_COLOR     = "|c00AFAFAF"

local NDKP_SortTypeCurrent		= "name"
local SORT_ORDER				= false
--local IS_FILTER				= false
--local FILTER					= ""
--local NDKP_ChatFrame			= nil;

local SHOW_NOTINRAID = true
local NDKP_default_ChatLines=10;

NDKP_Frames = {	'NDKP_Frame', 
				'NDKP_OptionsFrame', 
				'NDKP_BackUpFrame', 
				'NDKP_LogFrame'
			}

NDKP_Config_Default = {
	showMinimap 	= true,
	MinimapPos		= 45,
	AutoAnswear		= true,
	BackUp 			= {},
	
}	
		
--local RaidList = ""
--local RaidRanks = {}
--local RaidClasses = {}
local Classes = {}
NDKP_Table = {}
--if not NDKP_Spent then NDKP_Spent = {} end
--NDKP_FilteredTable = {}

local UnCheckAll = 0;

local ROSTER_BUTTON_OFFSET = 2;
local ROSTER_BUTTON_HEIGHT = 22;
local NDKP_Selected = {}

--NDKP_Spent = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
--NDKP_table_sorted={}
--NDKP_Selected_Member=0;
--NDKP_Selected_InTable=0;

local function round(number, decimals)
    return (("%%.%df"):format(decimals)):format(number)
end


local LOG_COLORS = {
	"|c00FF0000",  	--red
	"|c00FFFF00",  	-- yellow
	"|c0066CD00", 	-- green
	"|c00FFFFFF", 	-- white
	"|c00C0C0C0", 	-- grey
	"|c00FFFF00",  	-- local lvl
};
local LOG_TIME_COLOR = "|c0090FF90";


--[[Classes[NDKP_Priests]	= { color="|c00FFFFFF", id=1, left=0.50, right=0.75, bottom=0.25, top=0.50, checked = true  };
Classes[NDKP_Mages] 	= { color="|c0068CCEF", id=2, left=0.25, right=0.50, bottom=0.00, top=0.25, checked = true  };
Classes[NDKP_Warlocks] 	= { color="|c009382c9", id=3, left=0.75, right=1.00, bottom=0.25, top=0.50, checked = true  };
Classes[NDKP_Druids] 	= { color="|c00FF7C0A", id=4, left=0.75, right=1.00, bottom=0.00, top=0.25, checked = true  };
Classes[NDKP_Hunters] 	= { color="|c00AAD372", id=5, left=0.00, right=0.25, bottom=0.25, top=0.50, checked = true  };
Classes[NDKP_Rogues] 	= { color="|c00FFF468", id=6, left=0.50, right=0.75, bottom=0.00, top=0.25, checked = true  };
Classes[NDKP_Warriors]	= { color="|c00C69B6D", id=7, left=0.00, right=0.25, bottom=0.00, top=0.25, checked = true  };
Classes[NDKP_Paladins]	= { color="|c00F48CBA", id=8, left=0.00, right=0.25, bottom=0.50, top=0.75, checked = true  };
Classes[NDKP_Shamans]	= { color="|c0024FCDA", id=9, left=0.25, right=0.50, bottom=0.25, top=0.50, checked = true  };
Classes[NDKP_Monks]		= { color="|c0000FF96", id=10, left=0.25, right=0.50, bottom=0.00, top=0.25, checked = true };]]

Classes = {
	["WARRIOR"]		= {ClassFilterName = "Воины", 			checked = true,		ClassLocalName = "Воин",},
	["MAGE"]		= {ClassFilterName = "Маги", 			checked = true,		ClassLocalName = "Маг",},
	["ROGUE"]		= {ClassFilterName = "Разбойники", 		checked = true,		ClassLocalName = "Разбойник",},
	["DRUID"]		= {ClassFilterName = "Друиды", 			checked = true,		ClassLocalName = "Друид",},
	["HUNTER"]		= {ClassFilterName = "Охотники", 		checked = true,		ClassLocalName = "Охотник",},
	["SHAMAN"]	 	= {ClassFilterName = "Шаманы", 			checked = true,		ClassLocalName = "Шаман",},
	["PRIEST"]		= {ClassFilterName = "Жрецы", 			checked = true,		ClassLocalName = "Жрец",},
	["WARLOCK"]		= {ClassFilterName = "Чернокнижники", 	checked = true,		ClassLocalName = "Чернокнижник",},
	["PALADIN"]		= {ClassFilterName = "Паладины", 		checked = true,		ClassLocalName = "Паладин",},
	["DEATHKNIGHT"]	= {ClassFilterName = "Рыцари смерти", 	checked = true,		ClassLocalName = "Рыцарь смерти",},
	["MONK"]		= {ClassFilterName = "Монахи", 			checked = true,		ClassLocalName = "Монах",},
};

function NDKP_OnLoad(self)
	self:RegisterEvent("GUILD_ROSTER_UPDATE");
	self:RegisterEvent("CHAT_MSG_RAID");
	self:RegisterEvent("CHAT_MSG_SAY");
	self:RegisterEvent("VARIABLES_LOADED");
	self:RegisterEvent("CHAT_MSG_ADDON");
	RegisterAddonMessagePrefix("NDKP")
	NDKP_RosterContainer.update = NDKP_Roster_Update;
	HybridScrollFrame_CreateButtons(NDKP_RosterContainer, "NDKP_LineTemplate", 20, 0, "TOPLEFT", "TOPLEFT", 0, -2, "TOP", "BOTTOM");
	NDKP_RosterContainerScrollBar.doNotHide = true;
end

function NDKP_OnShow(self)
	NDKP_LoadDB();
	if NDKP_LOADED then
		NDKP_Init();
		NDKP_Roster_Update();
	else 
		self:Hide()
		NDKP_DBG(1, true, NDKP_AddonLoadMsgError)
	end
end

function NDKP_OnEvent(self, event, ...)
	if event == "CHAT_MSG_ADDON" then
		--if isAdmin then return end
		local prefix, message, _, sender = ...
		--print(sender)
		if prefix == "NDKP" and sender ~= UnitName("player") then
			local lvl, msg = tonumber(string.sub(message, 1, 1)), string.sub(message, 2)
			NDKP_DBG(lvl, false, msg)
		end
	elseif event == "CHAT_MSG_RAID"	and isAdmin then
		if not NDKP_Config.AutoAnswear then return end
		--("message", "sender", "language", "channelString", "target", "flags", unknown, channelNumber, "channelName", unknown, counter)
		local msg, name = ... ;
		
		local f = false;
		if msg == "min" or msg == "мин" then
			for k, v in pairs(NDKP_Table) do
				if NDKP_Table[k].name == name then 
					--print(NDKP_Table[k].name)
					f = true;
					SendChatMessage(format(NDKP_PrintDKP_ToRaid, NDKP_Table[k].name, (tonumber(round(NDKP_Table[k].cur/100*20, 0)) > 0 and round(NDKP_Table[k].cur/100*20, 0) or 0)), "RAID")
				end
			end
			if not f then 
				SendChatMessage(format(NDKP_PrintDKP_NOT_FOUND, name), "RAID")
			end
		end
	elseif event == "CHAT_MSG_SAY" and isAdmin then
		if not NDKP_Config.AutoAnswear then return end
		local msg, name = ... ;
		--print(msg.." "..name)
		local f = false;
		if msg == "min" or msg == "мин" then
			for k, v in pairs(NDKP_Table) do
				--print(NDKP_Table[k].name)
				if NDKP_Table[k].name == name then 
					f = true;
					SendChatMessage(format(NDKP_PrintDKP_ToRaid, NDKP_Table[k].name, (tonumber(round(NDKP_Table[k].cur/100*20, 0)) > 0 and round(NDKP_Table[k].cur/100*20, 0) or 0)), "SAY")
				end
			end
			if not f then 
				SendChatMessage(format(NDKP_PrintDKP_NOT_FOUND, name), "SAY")
			end
		end
	elseif event == "VARIABLES_LOADED" then
		--print("!")
		if not NDKP_Config then 
			NDKP_Config = {} 
			for k,v in pairs(NDKP_Config_Default) do
				NDKP_Config[k] = v
			end
		end
		NDKP_MinimapButton_Reposition()
		NDKP_ShowMM:SetChecked(NDKP_Config.showMinimap)
		NDKP_AutoAnswear:SetChecked(NDKP_Config.AutoAnswear) 
		NDKP_LoadDB()
	end
	
	
	if not _G["NDKP_Main_Frame"]:IsShown() then return end;
	
	if ( event == "GUILD_ROSTER_UPDATE" ) then
		if NDKP_LOADED then
			NDKP_LoadDB();
			NDKP_Roster_Update()
			NDKP_ApplyFilter()
			SORT_ORDER = not SORT_ORDER
			NDKP_ChangeSort(NDKP_SortTypeCurrent);
		end
	--elseif ( event == "PLAYER_ENTERING_WORLD" ) then
		--print(event)
		--[[NDKP_LoadDB();
		NDKP_Init()
		NDKP_Roster_Update()]]
	elseif (event == "GROUP_ROSTER_UPDATE") then
		NDKP_ApplyFilter()
	end
end

function NDKP_Init()
	
	NDKP_SortTypeCurrent = "name";
	SORT_ORDER = false;
	UnCheckAll = 0;
	wipe(NDKP_Selected);
	SHOW_NOTINRAID = true
	--SORT_ORDER = not SORT_ORDER
	NDKP_ChangeSort(NDKP_SortTypeCurrent);
	
	for k,v in pairs(Classes) do
		v.checked = true
	end
	
	getglobal("NDKP_Title_NickArrow"):SetTexCoord(0,0.5625,0,1);
	getglobal("ShowNotInRaidButton"):SetChecked(true);
end

--[[function NDKPsplit(str, pat)
   local t = {}  -- NOTE: use {n = 0} in Lua-5.0
   local fpat = "(.-)" .. pat
   local last_end = 1
   local s, e, cap = str:find(fpat, 1)
   while s do
      if s ~= 1 or cap ~= "" then
	 table.insert(t,cap)
      end
      last_end = e+1
      s, e, cap = str:find(fpat, last_end)
   end
   if last_end <= #str then
      cap = str:sub(last_end)
      table.insert(t, cap)
   end
   return t
end

function NDKPGetDKPString(str, StartStr, EndStr, Sep)
	local TextStart = string.find(str, StartStr) and (string.find(str, StartStr)+string.len(StartStr)) or 0;
	local TextEnd = string.find(str, EndStr) and (string.find(str, EndStr)-1) or 0;
	local Text = string.sub(str, TextStart, TextEnd);
	return Text
end

function GetGuildTable(str, StartStr, EndStr, Sep)
	local t = {}
	local Text = NDKPGetDKPString(str, StartStr, EndStr, Sep)
	if string.len(Text) > 0 then 
		t = NDKPsplit(Text, Sep);  
	end
	return t;
end]]

function NDKP_LoadDB()
	local j = 0
	for i = 1, GetNumGuildMembers() do
		local name, _, _, level, class, _, _, officernote, _, _, classFileName, _, _, _, _ = GetGuildRosterInfo(i);
		if string.find(officernote, "dkp%d+") then 
			local dkp = tonumber(string.match(string.match(officernote, "dkp%d+"), "%d+"));
			--NDKP_Table[id] = {class = class, classFileName = classFileName, name = name, spent = (tonumber(DKP_SpentTable_byID[id] or 0)), cur = (tonumber(DKP_Table_byID[id]) or 0), id = id, visible = true};
			NDKP_Table[j+1] = {class = class, 
								classFileName = classFileName, 
								name = name, 
								spent = tonumber(string.match(string.match(officernote, '/.*/') or '0', '%d+')), 
								cur = (dkp or 0), 
								visible = true,
								isAlt = false,
								mainName = nil,
								id = j+1,
								}
			--NDKP_DBG(1, true, "FOUND! "..name.." dkp = "..dkp)
			--print(name.." "..id)
			j = j+1;
		end;
	end
	
	if #NDKP_Table ~= 0 then NDKP_LOADED = true; end

end

--[[NDKP_Table_ = {
	[1] = {class = 'Воин', 			classFileName = 'WARRIOR', 		name = 'Atror01', spent = random(1 , 1000), cur = random(1 , 1000), id=1, visible = true},
	[2] = {class = 'Маг', 			classFileName = 'MAGE', 		name = 'Atror02', spent = random(1 , 1000), cur = random(1 , 1000), id=2, visible = true},
	[3] = {class = 'Разбойник', 	classFileName = 'ROGUE', 		name = 'Atror03', spent = random(1 , 1000), cur = random(1 , 1000), id=3, visible = true},
	[4] = {class = 'Друид', 		classFileName = 'DRUID', 		name = 'Atror04', spent = random(1 , 1000), cur = random(1 , 1000), id=4, visible = true},
	[5] = {class = 'Охотник', 		classFileName = 'HUNTER', 		name = 'Atror05', spent = random(1 , 1000), cur = random(1 , 1000), id=5, visible = true},
	[6] = {class = 'Шаман', 		classFileName = 'SHAMAN', 		name = 'Atror06', spent = random(1 , 1000), cur = random(1 , 1000), id=6, visible = true},
	[7] = {class = 'Жрец', 			classFileName = 'PRIEST', 		name = 'Atror07', spent = random(1 , 1000), cur = random(1 , 1000), id=7, visible = true},
	[8] = {class = 'Чернокнижник', 	classFileName = 'WARLOCK', 		name = 'Atror08', spent = random(1 , 1000), cur = random(1 , 1000), id=8, visible = true},
	[9] = {class = 'Паладин', 		classFileName = 'PALADIN', 		name = 'Atror09', spent = random(1 , 1000), cur = random(1 , 1000), id=9, visible = true},
	[10] = {class = 'Рыцарь смерти', classFileName = 'DEATHKNIGHT', name = 'Atror10', spent = random(1 , 1000), cur = random(1 , 1000), id=10, visible = true},
	[11] = {class = 'Монах', 		classFileName = 'MONK', 		name = 'Atror11', spent = random(1 , 1000), cur = random(1 , 1000), id=11, visible = true},
}]]


function NDKP_Roster_Update()

	local scrollFrame = NDKP_RosterContainer;
	local offset = HybridScrollFrame_GetOffset(scrollFrame);
	local buttons = scrollFrame.buttons;
	local numButtons = #buttons;
	local button, index, name, min, classFileName, spent, current, class, ID;
	local t = {}
	local visibleMembers = 0
	--if (#NDKP_FilteredTable ~= 0 or UnCheckAll == 1) then t=NDKP_FilteredTable else t = NDKP_Table end
	t = NDKP_Table
	--t=NDKP_FilteredTable
	local totalMembers = #t;
	local selectedMember = 1;
	local visibleOffset = 0;
	--NDKP_DBG(1, true, "numButtons "..numButtons)
	for k,v in pairs(t) do
		if v.visible then visibleMembers = visibleMembers+1 end
	end
	--print(visibleMembers.." "..totalMembers)
	--print(numButtons)
	for i = 1, numButtons do
		button = buttons[i];	
		button.icon:SetTexCoord(0, 0, 0, 0);
		button.nick:SetText("");	
		button.nick:SetTextColor(0, 0, 0, 0, 0);	
		button.min:SetText("");
		button.spent:SetText("");
		button.current:SetText("");
		button.className:SetText("");
		button.ID = 0; --index;
		button:Hide() 
	end
	
	for i = 1, numButtons do
		button = buttons[i-visibleOffset];	
			
		index = offset + i;
		--print(i.." "..index) 
		if index <=  totalMembers then
			name 			= t[index].name;
			min  			= tonumber(round(t[index].cur/100*20, 0)) > 0 and round(t[index].cur/100*20, 0) or 0;
			classFileName	= t[index].classFileName;
			spent			= t[index].spent;
			current			= t[index].cur;
			class			= t[index].class;
			visible			= t[index].visible;
			ID 				= t[index].id;
		else
			name, min, classFileName, spent, current, class, visible, ID  = NULL, NULL, NULL, NULL, NULL, false, NULL;
		end
		
		if name and not visible then visibleOffset = visibleOffset+1 end;
		--print("visibleOffset "..visibleOffset)
		
		--NDKP_DBG(1, true, "index "..index)
		if ( name and index <= totalMembers and visible) then
			button.icon:SetTexCoord(unpack(CLASS_ICON_TCOORDS[classFileName]));
			button.nick:SetText(name);	
			button.nick:SetTextColor(RAID_CLASS_COLORS[classFileName].r, RAID_CLASS_COLORS[classFileName].g, RAID_CLASS_COLORS[classFileName].b, 1);	
			button.min:SetText(min);
			button.spent:SetText(spent);
			button.current:SetText(current);
			button.className:SetText(class);
			button.ID = ID; --index;
			--NDKP_DBG(2, true, button.ID)
			button:Show();
			--if ( mod(i, 2) == 0 ) then
			if ( mod(i-visibleOffset, 2) == 0 ) then
				button.stripe:SetTexCoord(0.36230469, 0.38183594, 0.95898438, 0.99804688);
			else
				button.stripe:SetTexCoord(0.51660156, 0.53613281, 0.88281250, 0.92187500);
			end
			
			if NDKP_Selected[button.ID] then
				button:LockHighlight();
			else
				button:UnlockHighlight();
			end
			--visibleMembers = visibleMembers+1;
			--print(visibleMembers.." "..totalMembers)
		else
			button:Hide();
		end
		
	end
	--local totalHeight = totalMembers * (ROSTER_BUTTON_HEIGHT + ROSTER_BUTTON_OFFSET);
	local totalHeight = visibleMembers * (ROSTER_BUTTON_HEIGHT + ROSTER_BUTTON_OFFSET);
	local displayedHeight = numButtons * (ROSTER_BUTTON_HEIGHT + ROSTER_BUTTON_OFFSET);

	HybridScrollFrame_Update(scrollFrame, totalHeight, displayedHeight);
	--NDKP_DBG(3, true, "offset = "..HybridScrollFrame_GetOffset(scrollFrame))
end

function NDKP_GetTime()
	local hour, minute, sec = date("*t").hour, date("*t").min, date("*t").sec;
	local t = hour;
	if( hour < 10 ) then t = "0"..t; end
	t = t..":";
	if( minute < 10 ) then t = t.."0"; end
	t = t..minute;
	t = t..":";
	if( sec < 10 ) then t = t.."0"; end
	t = t..sec;
	return t;
end

function NDKP_DBG (lvl, toChat,  ...)
    local txt="";
	
	for i,v in pairs({...}) do
	    if(type(v)=="nil") then v="[nil]"; end
	    if(type(v)=="table") then v="[table]"; end
	    if(type(v)=="boolean") then v=tostring(v); end
	    txt=txt..v;
	end
	local txttime=LOG_TIME_COLOR.."["..NDKP_GetTime().."] ";
	NDKP_Log:AddMessage(txttime..LOG_COLORS[lvl]..txt)
	if toChat then DEFAULT_CHAT_FRAME:AddMessage(LOG_COLORS[lvl].."[NDKP] "..txt); end;
	
	--[[if isAdmin and lvl ~= 6 then
		SendAddonMessage("NDKP", lvl..txt, "PARTY")
	end]]
	--SendChatMessage("[NDKP] "..txt, "GUILD");
	--DEFAULT_CHAT_FRAME:AddMessage(LOG_COLORS[lvl].."[NDKP] "..txt);
end

function NDKP_Classes_Filter_OnLoad()

		info 					= UIDropDownMenu_CreateInfo();
		info.keepShownOnClick 	= false
		info.notCheckable 		= true;
		info.text       		= "Check All";
		info.func       		= NDKP_Classes_Filter_Click 
		info.arg1 				= k
		info.arg2 				= 1
		UIDropDownMenu_AddButton(info);

		info.notCheckable 		= true;
		info.text       		= "Uncheck All";
		info.func       		= NDKP_Classes_Filter_Click 
		info.arg1 				= k
		info.arg2 				= 2
		UIDropDownMenu_AddButton(info);
		
		info.keepShownOnClick 	= true
		
    for k, v in pairs(Classes) do
		info.notCheckable = false;	
		info.checked = v.checked;
		info.func = NDKP_Classes_Filter_Click;
		info.isNotRadio = true;
		info.text = v.ClassFilterName;		
		info.arg1 = k;
		info.arg2 = 3;
		UIDropDownMenu_AddButton(info)
	end
end

function NDKP_Classes_Filter_OnClick() 
    ToggleDropDownMenu(1, nil, NDKP_Classes_Filter_DropDownMenu, NDKP_Classes_Filter, 0, 0);
end

--[[function NDKP_ScrollFrame_Update()
	FauxScrollFrame_Update(NDKP_ScrollFrame,50,5,16);
end]]

function NDKP_Classes_Filter_Click(self, class, state, checked)
	UnCheckAll = 0
	if state == 1 then 
		for k,v in pairs(Classes) do Classes[k].checked = true end
	elseif state == 2 then 
		UnCheckAll = 1
		for k,v in pairs(Classes) do Classes[k].checked = false end
	elseif state == 3 then 	
		-- Сохранять инфу в конфиг файл нет нужды, потому как резетиться между сессиями.
		Classes[class].checked = self.checked;
	end
	NDKP_ApplyFilter();
end

function NDKP_ShowNotInRaid_OnClick(checked)
	SHOW_NOTINRAID = checked
	if SHOW_NOTINRAID then
		_G["NDKP_Main_Frame"]:UnregisterEvent("GROUP_ROSTER_UPDATE");
	else
		_G["NDKP_Main_Frame"]:RegisterEvent("GROUP_ROSTER_UPDATE");
	end
	NDKP_ApplyFilter()
end

function NDKP_ApplyFilter()
	if NDKP_DISABLE_FILTER then return end

	for k, v in ipairs(NDKP_Table) do
		
		if Classes[v.classFileName].checked then
			NDKP_Table[k].visible = true
		else
			NDKP_Table[k].visible = false
		end
		
		if not SHOW_NOTINRAID then 
			if UnitPlayerOrPetInRaid(NDKP_Table[k].name) and Classes[v.classFileName].checked then 
				NDKP_Table[k].visible = true
				--NDKP_DBG(3, true, "Unit "..NDKP_Table[k].name.." in my raid/group") ;
			else
				NDKP_Table[k].visible = false
				--NDKP_DBG(1, true, "Unit "..NDKP_Table[k].name.." is not in my raid/group");
			end
		end
	end

	NDKP_Roster_Update()
end

--[[function dNum(txt)
	if txt==nil then txt=0; end
	if type(txt)=="string" then txt=tonumber(txt); end
	if type(txt)~="number" then txt=0; end
	return txt;
end

function dStr(txt)
	if txt==nil then txt=""; end
	if type(txt)~="string" then txt=type(txt); end
	return txt;
end]]

function NDKP_ChangeSort(type)
	if NDKP_DISABLE_SORT then return end
	local top, bottom 
	
	--if type == "min" then NDKP_DBG(1, true, "Cant sort by this field!"); return end
	
	--if type == "min" then sortType = "cur" else sortType = type end
	
	--type = class, name, spent, cur, min
	local tab={ 
		["class"]='Class', 
		["name"]='Nick', 
		["min"]='Min',
		["spent"]='Spent', 
		["cur"]='Current'
	};
	
	NDKP_SortTypeOld = NDKP_SortTypeCurrent;

	--NDKP_FilteredTable
	
	if type == NDKP_SortTypeOld then
		SORT_ORDER = not SORT_ORDER
		if SORT_ORDER then 
			top=0; 
			bottom=1;
		else 
			top=1; 
			bottom=0;
		end
	else
		SORT_ORDER = true
		top, bottom = 0, 1
	end
	
	NDKP_SortTypeCurrent = type;
	
	--table.sort(NDKP_FilteredTable,
	table.sort(NDKP_Table,
		function(a,b)
			--local aa=a[sortType];
			--local bb=b[sortType];
			local aa=a[(type == "min" and "cur" or type)];
			local bb=b[(type == "min" and "cur" or type)];
			--[[if (type == 'cur' or type == 'spent' or type == 'min') then
				aa=dNum(aa);
				bb=dNum(bb);
			else
			    aa=dStr(aa);
			    bb=dStr(bb);
			end]]
			if SORT_ORDER then
				return aa < bb
			else
				return aa > bb
			end
		end
	)
	
	getglobal("NDKP_Title_"..tab[NDKP_SortTypeOld].."Arrow"):SetTexCoord(0,0,0,0);
	getglobal("NDKP_Title_"..tab[NDKP_SortTypeCurrent].."Arrow"):SetTexCoord(0,0.5625,top,bottom);
	
	NDKP_Roster_Update()
end

function NDKP_SetActiveTab(id)
	--NDKP_DBG(1, true, id);
	
	for k,v in pairs(NDKP_Frames) do
		if k==id then 
			_G[NDKP_Frames[k]]:Show()
		else	
			_G[NDKP_Frames[k]]:Hide()
		end
	end
end

function NDKP_Tab_OnCLick(self)
	--NDKP_DBG(1, true, self:GetName());
	NDKP_SetActiveTab(self:GetID());
	self:SetFrameLevel(NDKP_Main_Frame:GetFrameLevel()+1);
end

function NDKP_MessageFrameScrollButton_OnUpdate(self, elapsed)
	if (self:GetButtonState() == "PUSHED") then
		self.clickDelay = self.clickDelay - elapsed;
		if ( self.clickDelay < 0 ) then
			local name = self:GetName();
			if ( name == self:GetParent():GetName().."DownButton" ) then
				self:GetParent():ScrollDown();
			elseif ( name == self:GetParent():GetName().."UpButton" ) then
				self:GetParent():ScrollUp();
			end
			self.clickDelay = MESSAGE_SCROLLBUTTON_SCROLL_DELAY;
		end
	end
end

function NDKP_ChangeDKP(self, state)
	--NDKP_DBG(1, true, state);
	if state then
		if state == "Inc" then
			NDKPStaticPopup1TextTitle:SetText(NDKP_Inc_Text_Title);
			NDKPStaticPopup1TextDKP:SetText(NDKP_Inc_DKP_Text_Title);
			NDKPStaticPopup1TextReason:SetText(NDKP_Inc_Reason_Text_Title);
			NDKPStaticPopup1EditBox1:SetNumeric(false);
			NDKPStaticPopup1EditBox1:SetText(NDKP_Inc_DKP_Text);
			NDKPStaticPopup1EditBox1:SetNumeric(true);
			NDKPStaticPopup1EditBox2:SetText(NDKP_Inc_Reason_Text);
			NDKPStaticPopup1:SetID(1);
			NDKPStaticPopup1EditBox2:Show();
			NDKPStaticPopup1:Show();
			NDKPStaticPopup1EditBox1:SetFocus();
			NDKPStaticPopup1EditBox1:HighlightText(0, NDKPStaticPopup1EditBox1:GetNumLetters());
		elseif state == "Dec" then
			NDKPStaticPopup1TextTitle:SetText(NDKP_Dec_Text_Title);
			NDKPStaticPopup1TextDKP:SetText(NDKP_Dec_DKP_Text_Title);
			NDKPStaticPopup1TextReason:SetText(NDKP_Dec_Reason_Text_Title);
			NDKPStaticPopup1EditBox1:SetNumeric(false);
			NDKPStaticPopup1EditBox1:SetText(NDKP_Dec_DKP_Text);
			NDKPStaticPopup1EditBox1:SetNumeric(true);
			NDKPStaticPopup1EditBox2:SetText(NDKP_Dec_Reason_Text);
			NDKPStaticPopup1:SetID(2);
			NDKPStaticPopup1EditBox2:Show();
			NDKPStaticPopup1:Show();
			NDKPStaticPopup1EditBox1:SetFocus();
			NDKPStaticPopup1EditBox1:HighlightText(0, NDKPStaticPopup1EditBox1:GetNumLetters());
		elseif state == "Set" then
			NDKPStaticPopup1TextTitle:SetText(NDKP_Set_Text_Title);
			NDKPStaticPopup1TextDKP:SetText(NDKP_Set_DKP_Text_Title);
			NDKPStaticPopup1TextReason:SetText(NDKP_Set_Reason_Text_Title);
			NDKPStaticPopup1EditBox1:SetNumeric(false);
			NDKPStaticPopup1EditBox1:SetText(NDKP_Set_DKP_Text);
			NDKPStaticPopup1EditBox1:SetNumeric(true);
			NDKPStaticPopup1EditBox2:SetText(NDKP_Set_Reason_Text);
			NDKPStaticPopup1:SetID(3);
			NDKPStaticPopup1EditBox2:Show();
			NDKPStaticPopup1:Show();
			NDKPStaticPopup1EditBox1:SetFocus();
			NDKPStaticPopup1EditBox1:HighlightText(0, NDKPStaticPopup1EditBox1:GetNumLetters());
		elseif state == "Add" then
			NDKPStaticPopup1TextTitle:SetText(NDKP_Add_Text_Title);
			NDKPStaticPopup1TextDKP:SetText(NDKP_Add_DKP_Text_Title);
			NDKPStaticPopup1TextReason:SetText("");
			NDKPStaticPopup1EditBox1:SetNumeric(false);
			NDKPStaticPopup1EditBox1:SetText(NDKP_Add_DKP_Text);
			--NDKPStaticPopup1EditBox2:SetText(NDKP_Set_Reason_Text);
			NDKPStaticPopup1EditBox2:Hide();
			NDKPStaticPopup1:SetID(4);
			NDKPStaticPopup1:Show();
			NDKPStaticPopup1EditBox1:SetFocus();
			NDKPStaticPopup1EditBox1:HighlightText(0, NDKPStaticPopup1EditBox1:GetNumLetters());
		end
	end
end

--temptable = {}

--[[function NDKP_PrepareStrings()
	local GText = ""
	GText = GetGuildInfoText();
	
	local DKP_Table_byID = GetGuildTable(GText, "dkp*", "*dkp", "*")
	local DKP_SpentTable_byID = GetGuildTable(GText, "spent*", "*spent", "*")
	local Str1, Str2 = "", ""
	local t ={}
	
	for k,v in pairs(NDKP_Table) do
		t[v.id] = v
	end
	
	--temptable = t
	for i = 1, NDKPGetMaxID() do
		--Str1 = string.len(Str1) == 0 and ("dkp*"..(tostring(NDKP_Table[i].cur) or DKP_Table_byID[i])) or (Str1.."*"..(tostring(NDKP_Table[i].cur) or DKP_Table_byID[i]));
		--Str2 = string.len(Str2) == 0 and ("spent*"..(tostring(NDKP_Table[i].spent) or DKP_SpentTable_byID[i])) or (Str2.."*"..(tostring(NDKP_Table[i].spent) or DKP_SpentTable_byID[i]));
		Str1 = string.len(Str1) == 0 and ("dkp*"..(tostring(t[i].cur) or DKP_Table_byID[i])) or (Str1.."*"..(tostring(t[i].cur) or DKP_Table_byID[i]));
		Str2 = string.len(Str2) == 0 and ("spent*"..(tostring(t[i].spent) or DKP_SpentTable_byID[i])) or (Str2.."*"..(tostring(t[i].spent) or DKP_SpentTable_byID[i]));
	end
	Str1 = Str1.."*dkp"
	Str2 = Str2.."*spent"
		
	--print("Spent Line = "..Str2);
	--print("DKP line = "..Str1);
	
	local InfoText = ""
	
	local i = string.find(GText, "spent*")
	InfoText = string.sub(GText, 0, i-1);
	
	return Str1, Str2, InfoText
end]]

function NDKP_UpdateDKP(name, dkp, spent)
	local str, e, s
	if dkp < 0 then dkp = 0 end
	for i=1,GetNumGuildMembers() do 
		local _name,_,_,_,_,_,_, officernote = GetGuildRosterInfo(i)
		if _name == name then 
			s, e = string.find(officernote, '/.*/') 
			if s ~= nil then 
				str = string.sub(officernote,e+1)
			else 
				str = string.sub(officernote,7)
			end
			if dkp>99 then   
				GuildRosterSetOfficerNote(i,"dkp"..dkp.."/"..spent.."/"..str)
			elseif dkp>9 then
				GuildRosterSetOfficerNote(i,"dkp0"..dkp.."/"..spent.."/"..str)
			elseif dkp<10 then
				GuildRosterSetOfficerNote(i,"dkp00"..dkp.."/"..spent.."/"..str)
			end
		end
	end
end

function NDKPGetRealNum(id)
	for i = 1, NDKPGetMaxID() do
		if NDKP_Table[i].id == id then 
			return i 
		end
	end
end

function NDKP_Save_OnClick()
	local ResultStr = ""
	if NDKPStaticPopup1:GetID() ~= 4 then
		local dkp, reason
		dkp = tonumber(NDKPStaticPopup1EditBox1:GetText()) or 0;
		reason = NDKPStaticPopup1EditBox2:GetText();
		if NDKPStaticPopup1:GetID() == 1 then
			for k,v in pairs(NDKP_Selected) do
				NDKP_Table[NDKPGetRealNum(k)].cur = NDKP_Table[NDKPGetRealNum(k)].cur + dkp;
				ResultStr = string.len(ResultStr) == 0 and NDKP_Table[NDKPGetRealNum(k)].name or ResultStr..", "..NDKP_Table[NDKPGetRealNum(k)].name;
				NDKP_UpdateDKP(NDKP_Table[NDKPGetRealNum(k)].name, NDKP_Table[NDKPGetRealNum(k)].cur, NDKP_Table[NDKPGetRealNum(k)].spent)
			end
			NDKP_DBG(3, false, format(NDKP_Inc_Text_Format, dkp, ResultStr, reason));
			SendAddonMessage("NDKP", "3"..format(NDKP_Inc_Text_Format, dkp, ResultStr, reason), "GUILD")
		elseif NDKPStaticPopup1:GetID() == 2 then
			for k,v in pairs(NDKP_Selected) do
				NDKP_Table[NDKPGetRealNum(k)].cur = NDKP_Table[NDKPGetRealNum(k)].cur - dkp;
				NDKP_Table[NDKPGetRealNum(k)].spent = NDKP_Table[NDKPGetRealNum(k)].spent + dkp;
				ResultStr = string.len(ResultStr) == 0 and NDKP_Table[NDKPGetRealNum(k)].name or ResultStr..", "..NDKP_Table[NDKPGetRealNum(k)].name;
				NDKP_UpdateDKP(NDKP_Table[NDKPGetRealNum(k)].name, NDKP_Table[NDKPGetRealNum(k)].cur, NDKP_Table[NDKPGetRealNum(k)].spent)
			end
			NDKP_DBG(1, false, format(NDKP_Dec_Text_Format, dkp, ResultStr, reason))
			SendAddonMessage("NDKP", "1"..format(NDKP_Dec_Text_Format, dkp, ResultStr, reason), "GUILD")
		elseif NDKPStaticPopup1:GetID() == 3 then
			for k,v in pairs(NDKP_Selected) do
				NDKP_Table[NDKPGetRealNum(k)].cur = dkp;
				ResultStr = string.len(ResultStr) == 0 and NDKP_Table[NDKPGetRealNum(k)].name or ResultStr..", "..NDKP_Table[NDKPGetRealNum(k)].name;
				NDKP_UpdateDKP(NDKP_Table[NDKPGetRealNum(k)].name, NDKP_Table[NDKPGetRealNum(k)].cur, NDKP_Table[NDKPGetRealNum(k)].spent)
			end
			NDKP_DBG(2, false, format(NDKP_Set_Text_Format, dkp, ResultStr, reason))
			SendAddonMessage("NDKP", "2"..format(NDKP_Set_Text_Format, dkp, ResultStr, reason), "GUILD")
		end
		NDKP_Roster_Update()
		NDKPStaticPopup1:Hide();
	else
		local _name = NDKPStaticPopup1EditBox1:GetText()
		local name, level, class, officernote, classFileName, legal, idx
		for i = 1, GetNumGuildMembers() do
			name, _, _, level, class, _, _, officernote, _, _, classFileName, _, _, _, _ = GetGuildRosterInfo(i)
			if _name == name then 
				idx = i
				break; 
			end
		end
		if (name and name == _name) then
			legal = true
			for k,v in pairs(NDKP_Table) do
				if v.name == name then
					NDKP_DBG(1, true, NDKP_Add_Text_Exist);
					legal = false
					break;
				end
			end
			if level < NDKP_LEGAL_LEVEL then 
				NDKP_DBG(1, true, NDKP_Add_Text_Level); 
				legal = false;
			end
			if legal then
				local id = NDKPGetMaxID()+1;
				NDKP_Table[id] = {class = class, 
								classFileName = classFileName, 
								name = name, 
								spent = 0, 
								cur = 0, 
								visible = true,
								isAlt = false,
								mainName = nil,
								id = id,
								}
				NDKP_UpdateDKP(name, 0, 0)
				NDKP_Roster_Update()
			end
			
		else
			NDKP_DBG(1, true, NDKP_Add_Text_Guild);
		end

		NDKPStaticPopup1:Hide();
	end
	
	wipe(NDKP_Selected)
	NDKP_ApplyFilter()
end

function NDKPGetMaxID()
	local MaxID = 0
	for _,v in pairs(NDKP_Table) do
		if v.id > MaxID then MaxID = v.id end
	end
	return MaxID
end

local NDKP_menu = {
    { text = NDKP_Inc, notCheckable = true, arg1="Inc", func = NDKP_ChangeDKP },
    { text = NDKP_Dec, notCheckable = true, arg1="Dec", func = NDKP_ChangeDKP },
	{ text = NDKP_Set, notCheckable = true, arg1="Set", func = NDKP_ChangeDKP },
    { text = NDKP_AddMember, notCheckable = true, arg1="Add", func = NDKP_ChangeDKP },
}

function NDKP_PrintDKP(self, state)
	local CHANNEL, NAME = ""
	
	if state == "guild" then 
		NAME = GetGuildInfo("player")
		if NAME and NAME ~= "" then
			CHANNEL = "GUILD"
		else
			NDKP_DBG(1, true, NDKP_Chat_Error_Guild); 
			return
		end
	elseif state == "raid" then 
		if UnitPlayerOrPetInRaid("player") then
			CHANNEL = "RAID"
		else
			NDKP_DBG(1, true, NDKP_Chat_Error_Raid); 
			return
		end
	elseif state == "say" then 
		CHANNEL = "SAY"
	elseif state == "target" then 
		CHANNEL = "WHISPER"
		NAME, _ = UnitName("target")
		if not NAME or NAME == "" then 
			NDKP_DBG(1, true, NDKP_Chat_Error_Name); 
			return 
		end
	else 
		NDKP_DBG(1, true, NDKP_Chat_Error); 
		return; 
	end
	
	local i = 0
	
	if state == "target" then
		SendChatMessage(NDKP_PrintDKP_Title, CHANNEL, nil, NAME)
		for k,v in pairs(NDKP_Table) do
			if NDKP_Table[k].visible then
				i = i+1
				SendChatMessage(format(NDKP_PrintDKP_Text, i, NDKP_Table[k].name, NDKP_Table[k].cur, (tonumber(round(NDKP_Table[k].cur/100*20, 0)) > 0 and round(NDKP_Table[k].cur/100*20, 0) or 0)), CHANNEL, nil, NAME)
			end
		end
	else
		SendChatMessage(NDKP_PrintDKP_Title, CHANNEL)
		for k,v in pairs(NDKP_Table) do
			if NDKP_Table[k].visible then
				i = i+1
				SendChatMessage(format(NDKP_PrintDKP_Text, i, NDKP_Table[k].name, NDKP_Table[k].cur, (tonumber(round(NDKP_Table[k].cur/100*20, 0)) > 0 and round(NDKP_Table[k].cur/100*20, 0) or 0)), CHANNEL)
			end
		end
	end
end

local NDKP_smallmenu = {
    { text = NDKP_AddMember, notCheckable = true, arg1="Add", func = NDKP_ChangeDKP },
}

local NDKP_PrintMenu = {
    { text = NDKP_PrintGuild, notCheckable = true, arg1="guild", func = NDKP_PrintDKP },
	{ text = NDKP_PrintRaid, notCheckable = true, arg1="raid", func = NDKP_PrintDKP },
	{ text = NDKP_PrintSay, notCheckable = true, arg1="say", func = NDKP_PrintDKP },
	{ text = NDKP_PrintTarget, notCheckable = true, arg1="target", func = NDKP_PrintDKP },
}

local NDKP_menuFrame = 		CreateFrame("Frame", "NDKP_menuFrameName", 		UIParent, "UIDropDownMenuTemplate")
local NDKP_PrintMenuFrame = CreateFrame("Frame", "NDKP_PrintMenuFrameName", UIParent, "UIDropDownMenuTemplate")

function NDKP_RosterButton_OnClick(self, button)
	if ( button == "LeftButton" ) then
		--NDKP_DBG(2, true, button.." pressed")
		--NDKP_DBG(2, true, "self:ID = "..self.ID)
		
		if not IsControlKeyDown() then 
			wipe(NDKP_Selected)
			NDKP_Selected[self.ID]=true
			NDKP_Roster_Update()
		else
			NDKP_Selected[self.ID]=true
			NDKP_Roster_Update()
		end
		
	else
		--NDKP_DBG(2, true, button.." pressed")
		if isAdmin then 
			EasyMenu(NDKP_menu, NDKP_menuFrame, "cursor", 0 , 0, "MENU");
		end
		--NDKP_DBG(1, true, self.nick:GetText())
		if not NDKP_Selected[self.ID] then 
			wipe(NDKP_Selected) 
			NDKP_Selected[self.ID]=true
			NDKP_Roster_Update()
		end
	end
end

function NDKP_EmptyScrollFrame_OnClick(self, button)
	if ( button == "RightButton" and isAdmin) then
		EasyMenu(NDKP_smallmenu, NDKP_menuFrame, "cursor", 0 , 0, "MENU");
	end
end

function NDKP_ResetOptions_OnClick()
	if not NDKP_Config then 
		NDKP_Config = {} 
	else
		wipe(NDKP_Config)
	end
	for k,v in pairs(NDKP_Config_Default) do
		NDKP_Config[k] = v
	end
	NDKP_MinimapButton_Reposition()
	NDKP_ShowMM:SetChecked(NDKP_Config.showMinimap)
	NDKP_AutoAnswear:SetChecked(NDKP_Config.AutoAnswear)
end

function NDKP_PrintDKP_OnCLick(self, button)
	if ( button == "LeftButton" ) then
		NDKP_PrintMenuFrame:SetPoint("TOPLEFT", "NDKP_PrintDKPButton", "BOTTOMLEFT")
		EasyMenu(NDKP_PrintMenu, NDKP_PrintMenuFrame, NDKP_PrintMenuFrame, 0 , 30, "MENU");
		--print("OK")
	end
end

function NDKP_MinimapButton_Reposition()
	if not NDKP_Config.showMinimap then 
		NDKP_MinimapButton:Hide()
	else
		NDKP_MinimapButton:SetPoint("TOPLEFT","Minimap","TOPLEFT",52-(80*cos(NDKP_Config.MinimapPos)),(80*sin(NDKP_Config.MinimapPos))-52)
		if not NDKP_MinimapButton:IsVisible() then NDKP_MinimapButton:Show() end
	end
end

function NDKP_MinimapButton_DraggingFrame_OnUpdate()

	local xpos,ypos = GetCursorPosition()
	local xmin,ymin = Minimap:GetLeft(), Minimap:GetBottom()

	xpos = xmin-xpos/UIParent:GetScale()+70
	ypos = ypos/UIParent:GetScale()-ymin-70

	NDKP_Config.MinimapPos = math.deg(math.atan2(ypos,xpos))
	NDKP_MinimapButton_Reposition()
end

function NDKP_MinimapButton_OnClick()
	if NDKP_Main_Frame:IsVisible() then 
		NDKP_Main_Frame:Hide()
	else
		NDKP_Main_Frame:Show()
	end
end